#!/usr/bin/env python
#coding=utf-8
'''
Created on Aug 23, 2010
@author: lxd
'''
import types
from pyamf.remoting import RemotingError
import copy
import os
import itertools
import pyDes
import config

def desEncrypt(str):
    '''自定义可逆加密
    >>> data=desEncrypt('china')
    >>> desDecrypt(data)
    'china'
    '''
    k = pyDes.des("DESCRYPT", pyDes.CBC, "\0\0\0\0\0\0\0\0", pad=None, padmode=pyDes.PAD_PKCS5)
    return repr(k.encrypt(str))

def desDecrypt(str):
    '''自定义可逆解密
    '''
    k = pyDes.des("DESCRYPT", pyDes.CBC, "\0\0\0\0\0\0\0\0", pad=None, padmode=pyDes.PAD_PKCS5)
    return k.decrypt(eval(str))

def cookieStrToMap(s):
    '''
    >>> s = 'info=B; expires=Sun, 29-Aug-2010 06:38:38 GMT; path=/; domain=.pythonchallenge.com'
    >>> cookieStrToMap(s)
    {'info': 'B'}
    '''
    item_map = {}
    try:
        s.index(';')
    except ValueError:
        pass
    else:
        item_list = s.split(';')
        for item in item_list:
            (name, value) = item.split('=')
            item_map[name.strip()] = value.strip()
            
        item_map.pop('Path', '')   
        item_map.pop('path', '')   
        item_map.pop('domain', '')    
        item_map.pop('expires', '') 
    return item_map

def cookieMapToStr(map):
    '''
    >>> s={'info': 'B','sissionId':'abcdef'}
    >>> cookieMapToStr(s)
    'info=B;sissionId=abcdef'
    '''    
    cookies = ''
    if isinstance(map, types.DictType):
        cookies = ';'.join(['%s=%s' % (key, value) for key, value in map.items()])
    return cookies

def cookieObjToMap(cookies):
    #CookieJar专用
    cookie_map = {}
    if isinstance(cookies, types.ListType):
        for cookie in cookies:
            cookie_map[cookie.name] = cookie.value
    return cookie_map

def httpNoRedirectKeepAlive(url, referer, cookie):
    import httplib2
    httpHeaders = {
                'Connection':'keep-alive',
                'Keep-Alive':'115',
                'Referer':referer,
                'cookie':cookie,
                'Content-Type':'application/x-www-form-urlencoded',
                'user-agent':'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3',
                'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                'Accept-Encoding':'gzip,deflate',
                'Accept-Language':'en-us,en;q=0.5',
                'Accept-Charset':'x-gbk,utf-8;q=0.7,*;q=0.7',
               }     
    http = httplib2.Http()   
    http.follow_redirects = False
    return http.request(url, headers=httpHeaders)

def amfData(lst):
    from pyamf.amf3 import ByteArray
    data = ByteArray()
    if isinstance(lst, types.ListType):
        for l in lst:        
            data.writeUnsignedByte(l)
    return data

def encode(value):
    '''
    >>> value = 40777
    >>> encode(value) 
    [48, 130, 190, 125]
    '''        
    from pyamf import amf3
    b = amf3.ByteArray()
    key = "4784e4708d99d915d39ddf933497bbad"
    noise = 3
    
    b.writeObject(value)
    data = b.getvalue()
#    print '原始数据%s' % repr(data)
#    print '加密前数据%s' % [ord(i) for i in data]
    
    r = []
    for i in range(len(data)):
        if i % noise == 0:
            loc8 = i % len(key)
            r.append(ord(data[i]) ^ int(ord(key[loc8])))
        else:
            r.append(ord(data[i])) 
    return r  

def getLogger():     
    import logging
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)
    #create console handler and set level to info
    ch = logging.StreamHandler()
    ch.setLevel(logging.INFO)
    #create file handler and set level to debug
    fh = logging.FileHandler('log.log', 'w')
    fh.setLevel(logging.DEBUG)
    #create formatter
    formatter = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s')
    #add formatter to ch and fh
    ch.setFormatter(formatter)
    fh.setFormatter(formatter)
    #add ch and fh to logger
    logger.addHandler(ch)
    logger.addHandler(fh)
    return logger   

log = getLogger()   
#debug(), info(), warning(), error() and critical()

def postData(client, serviceName, funName, *args):
    result = None
    service = client.getService(serviceName)
    if args:
        data = []
        for arg in args:    
            data.append(amfData(encode(arg)))
        try:
            result = getattr(service, funName)(*data) 
        except RemotingError, err:
            log.error((RemotingError, err))
            raise RemotingError
    else:
        try:
            result = getattr(service, funName)() 
        except RemotingError, err:
            log.error((RemotingError, err))
            raise RemotingError
    return result 

def getMissionList(missions, user, inProgressMission=None):
    '''增加了timeDis字段
    >>> import config 
    >>> import configTest
    >>> user=configTest.user
    >>> inProgressMession={'dMId':1, 'timeDis':123}
    >>> mission_list=getMissionList(config.missions,user,inProgressMession)
    >>> len(mission_list)
    6
    >>> mission_list[0]['timeDis']
    123
    >>> mission_list[1]['timeDis']
    '-----'
    '''
    mission_list = []
    
    #添加正在进行的任务
    if inProgressMission:
        missions = copy.deepcopy(missions)
        for m in missions:
            if m['id'] == inProgressMission['dMId']:
                m['timeDis'] = inProgressMission['timeDis'] 
                mission_list.append(m) 
                break          
    
    #自动排出可做的任务            
    if user.militaryPoint >= user.polityPoint:
        kind = 'military'
    else:
        kind = 'polity'
    action = user.actionPoint - user.usedActPoint#可用的行动力      
    missions = copy.deepcopy(missions)
    missions.sort(key=lambda x:-x['level'])#倒序排列  
    while action > 0:
        for m in missions:
            if m['level'] <= user.rankId and m['kind'] == kind and m['action'] <= action:
                m['timeDis'] = config.blank
                mission_list.append(copy.deepcopy(m)) 
                action -= m['action']
                break
        else:
            break
    return mission_list
            
def getMissionByName(missions, name):
    '''
    >>> import config 
    >>> getMissionByName(config.missions,'追捕刑徒')
    {'action': 1000, 'kind': 'military', 'id': 8, 'name': u'\u8ffd\u6355\u5211\u5f92', 'level': 40}
    '''    
    for m in missions:
        if m['name'] == name:
            return copy.deepcopy(m) 
        
def getUpdateBuildList(builds):
    '''
    >>> import configTest
    >>> builds=configTest.builds
    >>> build_list=getUpdateBuildList(builds)
    >>> len(build_list)
    26
    >>> getUpdateBuildList(None)
    []
    '''
    if builds:
        builds = copy.deepcopy(builds)
        builds = [b for b in builds if b.isBuilding == -1]   #不是正在建造的     
        updateBuilds_list = sorted(builds, key=lambda x:x.level)#排序    
    else:
        updateBuilds_list = []
    return updateBuilds_list

def findFileNames(files):
    '''
    >>> files=['23.3.info','D://workspace//abc.info']
    >>> findFileNames(files)
    ['23.3', 'abc']
    '''
    r = []
    for file in files:
        afile = os.path.basename(file)
        r.append('.'.join(afile.split('.')[:-1]))
    return r
    
def getMaxLevelItems(builds_list):
    '''
    >>> builds_list = [[u'1137418', u'\u4fee\u70bc\u9986', u'4'], [u'2237418', u'\u4fee\u70bc\u9986', u'4'], [u'1137418', u'\u4fee\u70bc\u9986', u'15']]
    >>> getMaxLevelItems(builds_list)  
    [[u'1137418', u'\u4fee\u70bc\u9986', u'15'], [u'2237418', u'\u4fee\u70bc\u9986', u'4']]
    >>> builds_list = []
    >>> getMaxLevelItems(builds_list)  
    []
    '''
    data = copy.deepcopy(builds_list)
    nameKey = lambda x:x[0]
    data.sort(key=nameKey)
    r = []
    for key, group in itertools.groupby(data, nameKey):
        r.append(max(group, key=lambda x:int(x[2])))
    return r

def getBuildById(builds, id):
    '''
    >>> import configTest
    >>> builds=configTest.builds
    >>> getBuildById(builds,1115716).casBuiId
    1115716
    '''
    if builds:  
        for build in builds:
            if build.casBuiId == id:
                return copy.deepcopy(build)
    return []
                
if __name__ == '__main__':
    import doctest
    doctest.testmod()
